const React = require("react");
const classNames = require('classnames');
const Button = require('./Button');
const PropTypes = React.PropTypes;
const CheckBox = require('./CheckBox');
const Input = require('./Input');

class Transfer extends React.Component {
    displayName = 'Transfer';

    static defaultProps = {
        sourceTitle: 'source',
        targetTitle: 'target',
        transdered: '',
        filter: false
    };

    static propTypes = {
        data: PropTypes.array,
        onChange: PropTypes.func,
        transdered: PropTypes.string,
        sourceTitle: PropTypes.string,
        targetTitle: PropTypes.string,
        filter: PropTypes.bool,
        style: PropTypes.object,
        className: PropTypes.string
    }

    state = {
        sourceDisable: true,
        targetDisable: true
    };

    getData (data, transdered) {
        const keys = transdered.split(',');
        const source = [];
        let target = [];
        if (data) {
            target = data.filter((item) => {
                if (keys.indexOf(item.id) > -1) {
                    return true;
                } else {
                    source.push(item);
                    return false;
                }
            });
        }

        return {source, target};
    }

    sourceChange = () => {
        const value = this.source.getValue();
        this.setState({
            sourceDisable: !value
        });
    }

    targetChange = () => {
        const value = this.target.getValue();
        this.setState({
            targetDisable: !value
        });
    }

    onFilter (type) {
        if (type === 'source') {
            this.sourceChange();
        }
        if (type === 'target') {
            this.targetChange();
        }
    }

    transferRight = () => {
        const checked = this.source.getChecked();
        this.source.removeCheckedData();
        this.target.addData(checked);
        if(this.props.onChange){
            this.props.onChange();
        }
    }

    transferLeft = () => {
        const checked = this.target.getChecked();
        this.target.removeCheckedData();
        this.source.addData(checked);
        if(this.props.onChange){
            this.props.onChange();
        }
    }

    render () {
        const {className, style} = this.props;
        const clazzName = classNames('cm-transfer', className, {
            'cm-transfer-filter': this.props.filter
        });

        const data = this.getData(this.props.data, this.props.transdered);
        return (
            <div className={clazzName} style={style}>
                <List ref={(f) => this.source = f} 
                    filter={this.props.filter}
                    title={this.props.sourceTitle}
                    data={data.source}
                    onChange={this.sourceChange}
                    onFilter={this.onFilter.bind(this, 'source')}
                />
                <span className='cm-transfer-ops' style={{verticalAlign: 'middle', display: 'inline-block'}}>
                    <div>
                        <Button onClick={this.transferRight} icon='angle-right' font='cmui' theme='primary' disabled={this.state.sourceDisable}></Button>
                    </div>
                    <Button onClick={this.transferLeft} icon='angle-left' font='cmui' theme='primary' disabled={this.state.targetDisable}></Button>
                </span>
                <List ref={(f) => this.target = f} 
                    filter={this.props.filter}
                    title={this.props.targetTitle}
                    data={data.target}
                    onChange={this.targetChange}
                    onFilter={this.onFilter.bind(this, 'target')}
                />
            </div>
        );
    }
}


class List extends React.Component {
    displayName = 'List';

    static propTypes = {
        data: PropTypes.array,
        onChange: PropTypes.func
    }

    state = {
        allChecked: false,
        data: this.props.data || []
    };

    checkedKeys = [];

    renderList () {
        const {data} = this.state;
        return data.map((item) => {
            return <div className='cm-transfer-item' key={item.id} style={{display: item.__show ? 'block' : 'none'}}>
                <CheckBox checked={item.checked} disabled={item.disabled} label={item.text} onChange={this.itemCheckedChange.bind(this, item)}/>
            </div>;
        });
    }

    filter = () => {
        window.setTimeout(()=>{
            const keyWord = this.filterInput.getValue();
            const {data} = this.state;
            data.forEach((item) => {
                if (item.text.indexOf(keyWord) > -1) {
                    item.__show = true;
                } else {
                    item.__show = false;
                }
            });
    
            const ret = this.isAllChecked();
    
            this.setState({
                data,
                allChecked: ret.allChecked,
                value: ret.value
            }, () => {
                if (this.props.onFilter) {
                    this.props.onFilter();
                }
            });
        }, 0);
    }

    allCheckedChange = (v, checked) => {
        const {data} = this.state;
        this.checkedKeys = [];
        data.forEach((item) => {
            if (!item.disabled && item.__show) {
                item.checked = checked;
                if (checked) {
                    this.checkedKeys.push(item.id);
                }
            }
        });
        this.setState({
            data,
            allChecked: checked,
            value: this.checkedKeys.join(',')
        }, () => {
            if (this.props.onChange) {
                this.props.onChange();
            }
        });
    }

    isAllChecked () {
        const {data} = this.state;
        let checkedNum = 0;
        this.checkedKeys = [];
        const showData = data.filter((item) => {
            return item.__show;
        });
        showData.forEach((item) => {
            if (!item.disabled) {
                if (item.checked) {
                    checkedNum ++;
                    this.checkedKeys.push(item.id);
                }
            } else {
                checkedNum ++;
            }
        });
        let allChecked = false;
        if (checkedNum !== 0 && checkedNum === showData.length) {
            allChecked = true;
        }

        return {
            allChecked,
            value: this.checkedKeys.join(',')
        };
    }

    itemCheckedChange = (aItem, v, checked) => {
        aItem.checked = checked;
        const ret = this.isAllChecked();
        this.setState({
            allChecked: ret.allChecked,
            value: ret.value
        }, () => {
            if (this.props.onChange) {
                this.props.onChange();
            }
        });
    }

    getValue () {
        return this.state.value;
    }

    getChecked () {
        const {data} = this.state;
        const checked = [];
        data.forEach((item) => {
            if (!item.disabled && item.__show) {
                if (item.checked) {
                    checked.push(item);
                }
            }
        });
        return checked;
    }

    addData (data) {
        if (data) {
            data = data.map((item) => {
                item.checked = false;
                return item;
            });

            const newData = this.state.data.concat(data);
            this.setState({
                data: newData,
                allChecked: false
            }, () => {
                if (this.props.onChange) {
                    this.props.onChange();
                }
            });
        }
    }

    removeCheckedData () {
        let {data} = this.state;
        data = data.filter((item) => {
            if (item.disabled) {
                return true;
            }
            if (!item.__show) {
                return true;
            }
            return !item.checked;
        });
        this.setState({
            data,
            allChecked: false,
            value: ''
        }, () => {
            if (this.props.onChange) {
                this.props.onChange();
            }
        });
    }

    getData () {
        return this.state.data;
    }

    componentWillMount () {
        const {data} = this.state;
        data.forEach((item) => {
            item.__show = true;
        });
    }

    getShowSize () {
        const {data} = this.state;
        if (!data) {
            return 0;
        }
        const show = data.filter((item) => {
            return item.__show;
        });
        return show.length;
    }

    render () {
        const {className, style} = this.props;
        const clazzName = classNames('cm-transfer-list', className);
        
        return (
            <div className={clazzName} style={style}>
                <div className='cm-transfer-head'>
                    <CheckBox label={this.props.title} checked={this.state.allChecked} onChange={this.allCheckedChange}/>
                    <span className='pull-right'>总数: {this.getShowSize()}</span>
                </div>
                {this.props.filter ? <div className='cm-transfer-filter-wrap'>
                    <Input ref={(f) => this.filterInput = f} onInput={this.filter}/>
                </div> : null}
                <div className='cm-transfer-body'>
                    {this.renderList()}
                </div>
            </div>
        );
    }
}

module.exports = Transfer;
